Skip to main content
Version: Next

Lead Scoring Prediction

An education company named X Education sells online courses to industry professionals. On any given day, many professionals who are interested in the courses land on their website and browse for courses.

The company markets its courses on several websites and search engines like Google. Once these people land on the website, they might browse the courses or fill up a form for the course or watch some videos. When these people fill up a form providing their email address or phone number, they are classified to be a lead. Moreover, the company also gets leads through past referrals. Once these leads are acquired, employees from the sales team start making calls, writing emails, etc. Through this process, some of the leads get converted while most do not. The typical lead conversion rate at X education is around 30%.

Now, although X Education gets a lot of leads, its lead conversion rate is very poor. For example, if, say, they acquire 100 leads in a day, only about 30 of them are converted. To make this process more efficient, the company wishes to identify the most potential leads, also known as ‘Hot Leads’. If they successfully identify this set of leads, the lead conversion rate should go up as the sales team will now be focusing more on communicating with the potential leads rather than making calls to everyone.

There are a lot of leads generated in the initial stage (top) but only a few of them come out as paying customers from the bottom. In the middle stage, you need to nurture the potential leads well (i.e. educating the leads about the product, constantly communicating, etc. ) in order to get a higher lead conversion.

X Education wants to select the most promising leads, i.e. the leads that are most likely to convert into paying customers. The company requires you to build a model wherein you need to assign a lead score to each of the leads such that the customers with higher lead score h have a higher conversion chance and the customers with lower lead score have a lower conversion chance. The CEO, in particular, has given a ballpark of the target lead conversion rate to be around 80%.

Note: The overview is taken directly from Kaggle: https://www.kaggle.com/datasets/amritachatterjee09/lead-scoring-dataset/data

!pip install xplainable
!pip install xplainable-client

Install Packages

!pip install xplainable
!pip install altair==5.4.1 #Upgrade this to work in Google Colab
!pip install xplainable-client
!pip install kaggle
Out:

Requirement already satisfied: xplainable in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (1.3.0)

Requirement already satisfied: xplainable-client>=1.0.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (1.2.8.post3)

Requirement already satisfied: hyperopt>=0.2.7 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (0.2.7)

Requirement already satisfied: numba>=0.57.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (0.60.0)

Requirement already satisfied: numpy>=2.0.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (2.0.2)

Requirement already satisfied: pandas>=2.2.3 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (2.3.0)

Requirement already satisfied: pyperclip>=1.8.2 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (1.9.0)

Requirement already satisfied: scikit-learn>=1.3.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (1.6.1)

Requirement already satisfied: scipy>=1.6.2 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (1.15.3)

Requirement already satisfied: urllib3>=1.26.5 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (2.4.0)

Requirement already satisfied: psutil>=5.9.4 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (7.0.0)

Requirement already satisfied: joblib>=1.2.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (1.5.1)

Requirement already satisfied: networkx>=2.8.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (3.4.2)

Requirement already satisfied: tqdm>=4.62.3 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (4.67.1)

Requirement already satisfied: ipython in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (8.36.0)

Requirement already satisfied: packaging in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (25.0)

Requirement already satisfied: requests in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable) (2.32.3)

Requirement already satisfied: six in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from hyperopt>=0.2.7->xplainable) (1.17.0)

Requirement already satisfied: future in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from hyperopt>=0.2.7->xplainable) (1.0.0)

Requirement already satisfied: cloudpickle in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from hyperopt>=0.2.7->xplainable) (3.1.1)

Requirement already satisfied: py4j in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from hyperopt>=0.2.7->xplainable) (0.10.9.9)

Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from numba>=0.57.0->xplainable) (0.43.0)

Requirement already satisfied: python-dateutil>=2.8.2 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from pandas>=2.2.3->xplainable) (2.9.0.post0)

Requirement already satisfied: pytz>=2020.1 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from pandas>=2.2.3->xplainable) (2025.2)

Requirement already satisfied: tzdata>=2022.7 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from pandas>=2.2.3->xplainable) (2025.2)

Requirement already satisfied: threadpoolctl>=3.1.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from scikit-learn>=1.3.0->xplainable) (3.6.0)

Requirement already satisfied: setuptools>=65.5.1 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable-client>=1.0.0->xplainable) (80.8.0)

Requirement already satisfied: decorator in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (5.2.1)

Requirement already satisfied: exceptiongroup in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (1.3.0)

Requirement already satisfied: jedi>=0.16 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (0.19.2)

Requirement already satisfied: matplotlib-inline in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (0.1.7)

Requirement already satisfied: pexpect>4.3 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (4.9.0)

Requirement already satisfied: prompt_toolkit<3.1.0,>=3.0.41 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (3.0.51)

Requirement already satisfied: pygments>=2.4.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (2.19.1)

Requirement already satisfied: stack_data in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (0.6.3)

Requirement already satisfied: traitlets>=5.13.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (5.14.3)

Requirement already satisfied: typing_extensions>=4.6 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable) (4.13.2)

Requirement already satisfied: wcwidth in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from prompt_toolkit<3.1.0,>=3.0.41->ipython->xplainable) (0.2.13)

Requirement already satisfied: parso<0.9.0,>=0.8.4 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from jedi>=0.16->ipython->xplainable) (0.8.4)

Requirement already satisfied: ptyprocess>=0.5 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from pexpect>4.3->ipython->xplainable) (0.7.0)

Requirement already satisfied: charset-normalizer<4,>=2 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from requests->xplainable) (3.4.2)

Requirement already satisfied: idna<4,>=2.5 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from requests->xplainable) (3.10)

Requirement already satisfied: certifi>=2017.4.17 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from requests->xplainable) (2025.4.26)

Requirement already satisfied: executing>=1.2.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from stack_data->ipython->xplainable) (2.2.0)

Requirement already satisfied: asttokens>=2.1.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from stack_data->ipython->xplainable) (3.0.0)

Requirement already satisfied: pure_eval in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from stack_data->ipython->xplainable) (0.2.3)

Requirement already satisfied: altair==5.4.1 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (5.4.1)

Requirement already satisfied: jinja2 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from altair==5.4.1) (3.1.6)

Requirement already satisfied: jsonschema>=3.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from altair==5.4.1) (4.23.0)

Requirement already satisfied: narwhals>=1.5.2 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from altair==5.4.1) (1.40.0)

Requirement already satisfied: packaging in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from altair==5.4.1) (25.0)

Requirement already satisfied: typing-extensions>=4.10.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from altair==5.4.1) (4.13.2)

Requirement already satisfied: attrs>=22.2.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from jsonschema>=3.0->altair==5.4.1) (25.3.0)

Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from jsonschema>=3.0->altair==5.4.1) (2025.4.1)

Requirement already satisfied: referencing>=0.28.4 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from jsonschema>=3.0->altair==5.4.1) (0.36.2)

Requirement already satisfied: rpds-py>=0.7.1 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from jsonschema>=3.0->altair==5.4.1) (0.25.1)

Requirement already satisfied: MarkupSafe>=2.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from jinja2->altair==5.4.1) (3.0.2)

Requirement already satisfied: xplainable-client in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (1.2.8.post3)

Requirement already satisfied: numpy>=2.0.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable-client) (2.0.2)

Requirement already satisfied: pandas>=2.2.3 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable-client) (2.3.0)

Requirement already satisfied: pyperclip in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable-client) (1.9.0)

Requirement already satisfied: Requests in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable-client) (2.32.3)

Requirement already satisfied: scikit_learn in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable-client) (1.6.1)

Requirement already satisfied: setuptools>=65.5.1 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable-client) (80.8.0)

Requirement already satisfied: urllib3 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable-client) (2.4.0)

Requirement already satisfied: xplainable in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable-client) (1.3.0)

Requirement already satisfied: python-dateutil>=2.8.2 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from pandas>=2.2.3->xplainable-client) (2.9.0.post0)

Requirement already satisfied: pytz>=2020.1 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from pandas>=2.2.3->xplainable-client) (2025.2)

Requirement already satisfied: tzdata>=2022.7 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from pandas>=2.2.3->xplainable-client) (2025.2)

Requirement already satisfied: six>=1.5 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from python-dateutil>=2.8.2->pandas>=2.2.3->xplainable-client) (1.17.0)

Requirement already satisfied: charset-normalizer<4,>=2 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from Requests->xplainable-client) (3.4.2)

Requirement already satisfied: idna<4,>=2.5 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from Requests->xplainable-client) (3.10)

Requirement already satisfied: certifi>=2017.4.17 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from Requests->xplainable-client) (2025.4.26)

Requirement already satisfied: scipy>=1.6.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from scikit_learn->xplainable-client) (1.15.3)

Requirement already satisfied: joblib>=1.2.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from scikit_learn->xplainable-client) (1.5.1)

Requirement already satisfied: threadpoolctl>=3.1.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from scikit_learn->xplainable-client) (3.6.0)

Requirement already satisfied: hyperopt>=0.2.7 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable->xplainable-client) (0.2.7)

Requirement already satisfied: numba>=0.57.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable->xplainable-client) (0.60.0)

Requirement already satisfied: psutil>=5.9.4 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable->xplainable-client) (7.0.0)

Requirement already satisfied: networkx>=2.8.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable->xplainable-client) (3.4.2)

Requirement already satisfied: tqdm>=4.62.3 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable->xplainable-client) (4.67.1)

Requirement already satisfied: ipython in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable->xplainable-client) (8.36.0)

Requirement already satisfied: packaging in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from xplainable->xplainable-client) (25.0)

Requirement already satisfied: future in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from hyperopt>=0.2.7->xplainable->xplainable-client) (1.0.0)

Requirement already satisfied: cloudpickle in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from hyperopt>=0.2.7->xplainable->xplainable-client) (3.1.1)

Requirement already satisfied: py4j in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from hyperopt>=0.2.7->xplainable->xplainable-client) (0.10.9.9)

Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from numba>=0.57.0->xplainable->xplainable-client) (0.43.0)

Requirement already satisfied: decorator in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (5.2.1)

Requirement already satisfied: exceptiongroup in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (1.3.0)

Requirement already satisfied: jedi>=0.16 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (0.19.2)

Requirement already satisfied: matplotlib-inline in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (0.1.7)

Requirement already satisfied: pexpect>4.3 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (4.9.0)

Requirement already satisfied: prompt_toolkit<3.1.0,>=3.0.41 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (3.0.51)

Requirement already satisfied: pygments>=2.4.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (2.19.1)

Requirement already satisfied: stack_data in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (0.6.3)

Requirement already satisfied: traitlets>=5.13.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (5.14.3)

Requirement already satisfied: typing_extensions>=4.6 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from ipython->xplainable->xplainable-client) (4.13.2)

Requirement already satisfied: wcwidth in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from prompt_toolkit<3.1.0,>=3.0.41->ipython->xplainable->xplainable-client) (0.2.13)

Requirement already satisfied: parso<0.9.0,>=0.8.4 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from jedi>=0.16->ipython->xplainable->xplainable-client) (0.8.4)

Requirement already satisfied: ptyprocess>=0.5 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from pexpect>4.3->ipython->xplainable->xplainable-client) (0.7.0)

Requirement already satisfied: executing>=1.2.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from stack_data->ipython->xplainable->xplainable-client) (2.2.0)

Requirement already satisfied: asttokens>=2.1.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from stack_data->ipython->xplainable->xplainable-client) (3.0.0)

Requirement already satisfied: pure_eval in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from stack_data->ipython->xplainable->xplainable-client) (0.2.3)

Requirement already satisfied: kaggle in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (1.7.4.5)

Requirement already satisfied: bleach in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (6.2.0)

Requirement already satisfied: certifi>=14.05.14 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (2025.4.26)

Requirement already satisfied: charset-normalizer in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (3.4.2)

Requirement already satisfied: idna in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (3.10)

Requirement already satisfied: protobuf in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (6.31.1)

Requirement already satisfied: python-dateutil>=2.5.3 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (2.9.0.post0)

Requirement already satisfied: python-slugify in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (8.0.4)

Requirement already satisfied: requests in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (2.32.3)

Requirement already satisfied: setuptools>=21.0.0 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (80.8.0)

Requirement already satisfied: six>=1.10 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (1.17.0)

Requirement already satisfied: text-unidecode in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (1.3)

Requirement already satisfied: tqdm in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (4.67.1)

Requirement already satisfied: urllib3>=1.15.1 in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (2.4.0)

Requirement already satisfied: webencodings in /Users/jtuppack/miniforge3/envs/xplainable-api/lib/python3.10/site-packages (from kaggle) (0.5.1)

Package Imports

import pandas as pd
from sklearn.model_selection import train_test_split
import requests
import json

import xplainable as xp
from xplainable.core.models import XClassifier
from xplainable.core.optimisation.bayesian import XParamOptimiser
from xplainable.preprocessing.pipeline import XPipeline
from xplainable.preprocessing import transformers as xtf

from xplainable_client.client.client import XplainableClient
from xplainable_client.client.base import XplainableAPIError

Instantiate Xplainable Cloud

Initialise the xplainable cloud using an API key from: https://platform.xplainable.io/

This allows you to save and collaborate on models, create deployments, create shareable reports with a free trial of 14 days.

# Initialize Xplainable Cloud client
client = XplainableClient(
api_key="", #Create api key in xplainable cloud - https://platform.xplainable.io/
hostname="https://platform.xplainable.io"
)
Out:

Connected to Xplainable Cloud

User: jtuppa

Hostname: http://localhost:8000

API Key Expires: 2025-09-04T10:30:18.154043

Python Version: 3.10.17

Xplainable Version: 1.3.0

Read Lead Scoring Dataset

Note: You can download the dataset to run this notebook from https://www.kaggle.com/datasets/amritachatterjee09/lead-scoring-dataset.

df = pd.read_csv('https://xplainable-public-storage.syd1.digitaloceanspaces.com/example_data/lead_scoring.csv')

Sample of the Lead Scoring Dataset

df.head()
Prospect IDLead NumberLead OriginLead SourceDo Not EmailDo Not CallConvertedTotalVisitsTotal Time Spent on WebsitePage Views Per Visit...Get updates on DM ContentLead ProfileCityAsymmetrique Activity IndexAsymmetrique Profile IndexAsymmetrique Activity ScoreAsymmetrique Profile ScoreI agree to pay the amount through chequeA free copy of Mastering The InterviewLast Notable Activity
07927b2df-8bba-4d29-b9a2-b6e0beafe620660737APIOlark ChatNoNo0000...NoSelectSelect02.Medium02.Medium1515NoNoModified
12a272436-5132-4136-86fa-dcc88c88f482660728APIOrganic SearchNoNo056742.5...NoSelectSelect02.Medium02.Medium1515NoNoEmail Opened
28cc8c611-a219-4f35-ad23-fdfd2656bd8a660727Landing Page SubmissionDirect TrafficNoNo1215322...NoPotential LeadMumbai02.Medium01.High1420NoYesEmail Opened
30cc2df48-7cf4-4e39-9de9-19797f9b38cc660719Landing Page SubmissionDirect TrafficNoNo013051...NoSelectMumbai02.Medium01.High1317NoNoModified
43256f628-e534-4826-9d63-4a8b88782852660681Landing Page SubmissionGoogleNoNo1214281...NoSelectMumbai02.Medium01.High1518NoNoModified

1. Data Preprocessing

#Instantiate a Pipeline
pipeline = XPipeline()

# Add stages for specific features
pipeline.add_stages([
{"transformer": xtf.DropCols(
columns=['Prospect ID', #-> Highly Cardinal,
"Lead Number", #-> Reduce Multicollinearity between Tenure and Monthly Costs
]
)},
])
Out:

<xplainable.preprocessing.pipeline.XPipeline at 0x16fc452d0>

Preprocessed data

df_transformed = pipeline.fit_transform(df)
df_transformed.head()
Lead OriginLead SourceDo Not EmailDo Not CallConvertedTotalVisitsTotal Time Spent on WebsitePage Views Per VisitLast ActivitySpecialization...Get updates on DM ContentLead ProfileCityAsymmetrique Activity IndexAsymmetrique Profile IndexAsymmetrique Activity ScoreAsymmetrique Profile ScoreI agree to pay the amount through chequeA free copy of Mastering The InterviewLast Notable Activity
0APIOlark ChatNoNo0000Page Visited on WebsiteSelect...NoSelectSelect02.Medium02.Medium1515NoNoModified
1APIOrganic SearchNoNo056742.5Email OpenedSelect...NoSelectSelect02.Medium02.Medium1515NoNoEmail Opened
2Landing Page SubmissionDirect TrafficNoNo1215322Email OpenedBusiness Administration...NoPotential LeadMumbai02.Medium01.High1420NoYesEmail Opened
3Landing Page SubmissionDirect TrafficNoNo013051UnreachableMedia and Advertising...NoSelectMumbai02.Medium01.High1317NoNoModified
4Landing Page SubmissionGoogleNoNo1214281Converted to LeadSelect...NoSelectMumbai02.Medium01.High1518NoNoModified

Create Preprocessor ID to persist to Xplainable Cloud


preprocessor_id, version_id = client.preprocessing.create_preprocessor(
preprocessor_name="Lead Scoring Preprocessing",
preprocessor_description="Predicting the Likelihood of a Lead Converting",
pipeline=pipeline,
df=df
)
preprocessor_id, version_id
Out:

('1IkLdZXzAEZfPJpE', '2yDjTGvCgVk0kmhE')

Loading the Preprocessor steps

Use the api to load pre-existing preprocessor steps from the xplainable cloud and transform data inplace.


pp_cloud = client.preprocessing.load_preprocessor(
version_id,
preprocessor_id,
)
pp_cloud.stages
Out:

[{'feature': '__dataset__',

'name': 'DropCols',

'transformer': <xplainable.preprocessing.transformers.dataset.DropCols at 0x16fbe7e80>}]

df_transformed_cloud = pp_cloud.transform(df)

df_transformed_cloud
Lead OriginLead SourceDo Not EmailDo Not CallConvertedTotalVisitsTotal Time Spent on WebsitePage Views Per VisitLast ActivitySpecialization...Get updates on DM ContentLead ProfileCityAsymmetrique Activity IndexAsymmetrique Profile IndexAsymmetrique Activity ScoreAsymmetrique Profile ScoreI agree to pay the amount through chequeA free copy of Mastering The InterviewLast Notable Activity
0APIOlark ChatNoNo00.000.00Page Visited on WebsiteSelect...NoSelectSelect02.Medium02.Medium15.015.0NoNoModified
1APIOrganic SearchNoNo05.06742.50Email OpenedSelect...NoSelectSelect02.Medium02.Medium15.015.0NoNoEmail Opened
2Landing Page SubmissionDirect TrafficNoNo12.015322.00Email OpenedBusiness Administration...NoPotential LeadMumbai02.Medium01.High14.020.0NoYesEmail Opened
3Landing Page SubmissionDirect TrafficNoNo01.03051.00UnreachableMedia and Advertising...NoSelectMumbai02.Medium01.High13.017.0NoNoModified
4Landing Page SubmissionGoogleNoNo12.014281.00Converted to LeadSelect...NoSelectMumbai02.Medium01.High15.018.0NoNoModified
..................................................................
9132Landing Page SubmissionDirect TrafficYesNo18.018452.67Email Marked SpamIT Projects Management...NoPotential LeadMumbai02.Medium01.High15.017.0NoNoEmail Marked Spam
9133Landing Page SubmissionDirect TrafficNoNo02.02382.00SMS SentMedia and Advertising...NoPotential LeadMumbai02.Medium01.High14.019.0NoYesSMS Sent
9134Landing Page SubmissionDirect TrafficYesNo02.01992.00SMS SentBusiness Administration...NoPotential LeadMumbai02.Medium01.High13.020.0NoYesSMS Sent
9135Landing Page SubmissionGoogleNoNo13.04993.00SMS SentHuman Resource Management...NonanOther Metro Cities02.Medium02.Medium15.016.0NoNoSMS Sent
9136Landing Page SubmissionDirect TrafficNoNo16.012793.00SMS SentSupply Chain Management...NoPotential LeadOther Cities02.Medium01.High15.018.0NoYesModified

Create Train/Test split for model training validation

X, y = df_transformed.drop(columns=['Converted']), df['Converted']

#Optional if you want to use the cloud preprocessor
# X, y = df_transformed_cloud.drop(columns=['Converted']), df_transformed_cloud['Converted']

X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.33, random_state=42)

2. Model Optimisation

The XParamOptimiser is utilised to fine-tune the hyperparameters of our model. This process searches for the optimal parameters that will yield the best model performance, balancing accuracy and computational efficiency.

opt = XParamOptimiser()
params = opt.optimise(X_train, y_train)
Out:

100%|██████████| 30/30 [00:03<00:00, 8.59trial/s, best loss: -0.8594330347239172]

3. Model Training

With the optimised parameters obtained, the XClassifier is trained on the dataset. This classifier undergoes a fitting process with the training data, ensuring that it learns the underlying patterns and can make accurate predictions.

model = XClassifier(**params)
model.fit(X_train, y_train)
Out:

<xplainable.core.ml.classification.XClassifier at 0x28fd6aef0>

4. Model Interpretability and Explainability

Following training, the model.explain() method is called to generate insights into the model's decision-making process. This step is crucial for understanding the factors that influence the model's predictions and ensuring that the model's behaviour is transparent and explainable.

model.explain()

The visualization displays feature importance and contribution analysis for the lead scoring prediction model.

The 'Feature Importances' chart ranks features by their ability to predict lead conversion probability. Key factors influencing lead scoring typically include engagement metrics, demographic information, and behavioral patterns from the lead's interactions.

The 'Contributions' chart shows how specific feature values impact individual predictions, helping understand what drives lead qualification decisions and enabling sales teams to prioritize high-quality prospects.

5. Model Persisting

In this step, we first create a unique identifier for our churn prediction model using client.create_model_id. This identifier, shown as model_id, represents the newly instantiated model which predicts the likelihood of customers leaving within the next month. Following this, we generate a specific version of the model with client.create_model_version, passing in our training data. The output version_id represents this particular iteration of our model, allowing us to track and manage different versions systematically.

# Create a model
model_id, version_id = client.models.create_model(
model=model,
model_name="Lead Scoring",
model_description="Predicting the likelihood of a lead converting",
x=X_train,
y=y_train
)
Out:

0%| | 0/32 [00:00<?, ?it/s]

6. Model Deployment

The code block illustrates the deployment of our churn prediction model using the client.deployments.deploy function. The deployment process involves specifying the hostname of the server where the model will be hosted, as well as the unique model_id and version_id that we obtained in the previous steps. This step effectively activates the model's endpoint, allowing it to receive and process prediction requests. The output confirms the deployment with a deployment_id, indicating the model's current status as 'inactive', its location, and the endpoint URL where it can be accessed for xplainable deployments.

if model_id and version_id:
try:
deployment_response = client.deployments.deploy(
model_version_id=version_id #<- Use version id produced above
)
deployment_id = deployment_response.deployment_id
except XplainableAPIError as e:
print(f"Error deploying model: {e}")
deployment_id = None
else:
deployment_id = None

Testing the Deployment programatically

This section demonstrates the steps taken to programmatically test a deployed model. These steps are essential for validating that the model's deployment is functional and ready to process incoming prediction requests.

  1. Activating the Deployment: The model deployment is activated using client.activate_deployment, which changes the deployment status to active, allowing it to accept prediction requests.
if deployment_id:
try:
client.deployments.activate_deployment(deployment_id=deployment_id)
except XplainableAPIError as e:
print(f"Error activating deployment: {e}")
else:
print("Deployment ID not available")
  1. Creating a Deployment Key: A deployment key is generated with client.deployments.generate_deploy_key. This key is required to authenticate and make secure requests to the deployed model.
if deployment_id:
try:
deploy_key = client.deployments.generate_deploy_key(
deployment_id=deployment_id,
description='API key for Lead Scoring Prediction',
days_until_expiry=30
)
print(f"Deploy key created: {str(deploy_key)}")
except XplainableAPIError as e:
print(f"Error generating deploy key: {e}")
deploy_key = None
else:
deploy_key = None
Out:

Deploy key created: 3272a7e2-9c28-4c8d-a3b8-cc70d2168619

  1. Generating Example Payload: An example payload for a deployment request is generated by client.generate_example_deployment_payload. This payload mimics the input data structure the model expects when making predictions.
#Set the option to highlight multiple ways of creating data
option = 2
df_transformed.columns
Out:

Index(['Lead Origin', 'Lead Source', 'Do Not Email', 'Do Not Call',

'Converted', 'TotalVisits', 'Total Time Spent on Website',

'Page Views Per Visit', 'Last Activity', 'Specialization',

'How did you hear about X Education', 'What is your current occupation',

'What matters most to you in choosing a course', 'Search', 'Magazine',

'Newspaper Article', 'X Education Forums', 'Newspaper',

'Digital Advertisement', 'Through Recommendations',

'Receive More Updates About Our Courses', 'Lead Quality',

'Update me on Supply Chain Content', 'Get updates on DM Content',

'Lead Profile', 'City', 'Asymmetrique Activity Index',

'Asymmetrique Profile Index', 'Asymmetrique Activity Score',

'Asymmetrique Profile Score',

'I agree to pay the amount through cheque',

'A free copy of Mastering The Interview', 'Last Notable Activity'],

dtype='object')

if option == 1 and version_id:
try:
body = client.deployments.generate_example_deployment_payload(
model_version_id=version_id
)
except XplainableAPIError as e:
print(f"Error generating example payload: {e}")
body = []
else:
body = json.loads(df_transformed.drop(columns=["Converted"]).sample(1).to_json(orient="records"))
body[0]["Gender"] = None #<- Won't require this line the next release of xplainable
body
Out:

[{'Lead Origin': 'API',

'Lead Source': 'Olark Chat',

'Do Not Email': 'No',

'Do Not Call': 'No',

'TotalVisits': 0.0,

'Total Time Spent on Website': 0,

'Page Views Per Visit': 0.0,

'Last Activity': 'SMS Sent',

'Specialization': 'Select',

'How did you hear about X Education': 'Select',

'What is your current occupation': 'Unemployed',

'What matters most to you in choosing a course': 'Better Career Prospects',

'Search': 'No',

'Magazine': 'No',

'Newspaper Article': 'No',

'X Education Forums': 'No',

'Newspaper': 'No',

'Digital Advertisement': 'No',

'Through Recommendations': 'No',

'Receive More Updates About Our Courses': 'No',

'Lead Quality': None,

'Update me on Supply Chain Content': 'No',

'Get updates on DM Content': 'No',

'Lead Profile': 'Select',

'City': 'Select',

'Asymmetrique Activity Index': None,

'Asymmetrique Profile Index': None,

'Asymmetrique Activity Score': None,

'Asymmetrique Profile Score': None,

'I agree to pay the amount through cheque': 'No',

'A free copy of Mastering The Interview': 'No',

'Last Notable Activity': 'SMS Sent',

'Gender': None}]

  1. Making a Prediction Request: A POST request is made to the model's prediction endpoint with the example payload. The model processes the input data and returns a prediction response, which includes the predicted class (e.g., 'No' for no churn) and the prediction probabilities for each class.
if deploy_key and body:
response = requests.post(
url="https://inference.xplainable.io/v1/predict",
headers={'api_key': str(deploy_key)},
json=body
)

value = response.json()
print("Prediction result:", value)
else:
print("Deploy key or body not available for prediction")
Out:

Prediction result: [{'index': 0, 'id': None, 'partition': '__dataset__', 'score': 0.5138461113290878, 'proba': 0.5402210582390248, 'pred': 1, 'support': 735, 'breakdown': [{'feature': 'base_value', 'value': None, 'score': 0.3806567554321189}, {'feature': 'Lead Origin', 'value': 'API', 'score': -0.010196328908133758}, {'feature': 'Lead Source', 'value': 'Olark Chat', 'score': -0.013443347877402288}, {'feature': 'Do Not Email', 'value': 'No', 'score': 0.004493683317418156}, {'feature': 'Do Not Call', 'value': 'No', 'score': -4.199526127277487e-05}, {'feature': 'TotalVisits', 'value': '0', 'score': 0.0058464572979032665}, {'feature': 'Total Time Spent on Website', 'value': '0', 'score': 0.005248030353684144}, {'feature': 'Page Views Per Visit', 'value': '0', 'score': 0.0058464572979032665}, {'feature': 'Last Activity', 'value': 'SMS Sent', 'score': 0.038624526799564095}, {'feature': 'Specialization', 'value': 'Select', 'score': 0.005284430725558849}, {'feature': 'How did you hear about X Education', 'value': 'Select', 'score': 0.01746576765048122}, {'feature': 'What is your current occupation', 'value': 'Unemployed', 'score': 0.010223832257095545}, {'feature': 'What matters most to you in choosing a course', 'value': 'Better Career Prospects', 'score': 0.02192016350910929}, {'feature': 'Search', 'value': 'No', 'score': 1.6986291775947786e-05}, {'feature': 'Magazine', 'value': 'No', 'score': 0.0}, {'feature': 'Newspaper Article', 'value': 'No', 'score': -8.092202152401614e-06}, {'feature': 'X Education Forums', 'value': 'No', 'score': 1.516954741157725e-05}, {'feature': 'Newspaper', 'value': 'No', 'score': 1.516954741157725e-05}, {'feature': 'Digital Advertisement', 'value': 'No', 'score': 5.658764870614314e-06}, {'feature': 'Through Recommendations', 'value': 'No', 'score': -1.6187579066188435e-05}, {'feature': 'Receive More Updates About Our Courses', 'value': 'No', 'score': 0.0}, {'feature': 'Lead Quality', 'value': 'nan', 'score': -0.026869076106841798}, {'feature': 'Update me on Supply Chain Content', 'value': 'No', 'score': 0.0}, {'feature': 'Get updates on DM Content', 'value': 'No', 'score': 0.0}, {'feature': 'Lead Profile', 'value': 'Select', 'score': 0.004735065585861729}, {'feature': 'City', 'value': 'Select', 'score': 0.014418320832047972}, {'feature': 'Asymmetrique Activity Index', 'value': 'nan', 'score': 0.000925234101816118}, {'feature': 'Asymmetrique Profile Index', 'value': 'nan', 'score': 0.000925234101816118}, {'feature': 'Asymmetrique Activity Score', 'value': 'nan', 'score': 0.000925234101816118}, {'feature': 'Asymmetrique Profile Score', 'value': 'nan', 'score': 0.000925234101816118}, {'feature': 'I agree to pay the amount through cheque', 'value': 'No', 'score': 0.0}, {'feature': 'A free copy of Mastering The Interview', 'value': 'No', 'score': 0.002540621639964162}, {'feature': 'Last Notable Activity', 'value': 'SMS Sent', 'score': 0.043363106006512095}]}]